package com.mjk.common.util;

import com.mjk.common.base.model.BaseEntity;
import com.mjk.common.tools.logger.BizLogger;

import java.util.ArrayList;
import java.util.List;

/**
 * 树形结构工具类
 */
public class TreeUtils {
    private TreeUtils() {
    }

    /**
     * list 转为 tree 功能
     *
     * @param lists          要转化的list
     * @param leavel         转化顶层ID
     * @param childField     子节点属性名称
     * @param parentField    父节点属性名称
     * @param childListField 儿子list节点
     * @param isSub
     * @param <K>
     * @return
     */
    public static <K extends BaseEntity> List<K> list2Tree(List<K> lists, String leavel, String childField, String parentField, String childListField, boolean isSub) {
        List<K> menu = new ArrayList<>();
        try {
            for (K m : lists) {
                if (ObjectUtils.isEmpty(leavel)) {
                    continue;
                }
                if (leavel.equals(getValue(m, parentField))) {
                    if (isSub) {
                        K tmp = (K) BeanUtils.toBean(m, m.getClass());
                        ReflectionUtils.setFieldValue(tmp, childListField, list2Tree(lists, getValue(tmp, childField).toString(), childField, parentField, childListField, true));
                        menu.add(tmp);
                    } else {
                        ReflectionUtils.setFieldValue(m, childListField, list2Tree(lists, getValue(m, childField).toString(), childField, parentField, childListField, true));
                        menu.add(m);
                    }
                }
            }
        } catch (Exception e) {
            BizLogger.error(e);
        }
        return menu;
    }

    /**
     * 查找特定字段值的节点以及其所有父节点直到根节点
     *
     * @param lists       要查找的列表
     * @param targetField 要查找的字段
     * @param targetValue 要查找的值
     * @param parentField 父节点属性名称
     * @param <K>
     * @return 包含目标节点及其父节点的路径
     */
    public static <K extends BaseEntity> List<K> findPathToRoot(List<K> lists, String targetField, String targetValue, String parentField) {
        List<K> path = new ArrayList<>();
        K targetNode = findNodeByField(lists, targetField, targetValue);

        if (targetNode != null) {
            path.add(targetNode);
            findParents(lists, targetNode, parentField, path);
        }

        return path;
    }

    private static <K extends BaseEntity> K findNodeByField(List<K> lists, String field, String value) {
        for (K node : lists) {
            if (value.equals(getValue(node, field))) {
                return node; // 找到目标节点
            }
        }
        return null; // 未找到
    }

    private static <K extends BaseEntity> void findParents(List<K> lists, K node, String parentField, List<K> path) {
        String parentId = (String) getValue(node, parentField);
        if (parentId == null || parentId.isEmpty()) {
            return; // 到达根节点
        }

        K parentNode = findNodeByField(lists, "id", parentId); // 假设 id 是唯一标识符
        if (parentNode != null) {
            path.add(0, parentNode); // 添加到路径开头
            findParents(lists, parentNode, parentField, path); // 递归查找父节点
        }
    }

    private static Object getValue(Object o, String fileName) {
        Object value = ReflectionUtils.getFieldValue(o, fileName);
        if (ObjectUtils.isEmpty(value)) {
            String fix = "$cglib_prop_";
            value = ReflectionUtils.getFieldValue(o, fix + fileName);
        }
        return value;
    }
}
